diff --git a/ExpressAPI/src/config/Config.ts b/ExpressAPI/src/config/Config.ts
index ae50eb18fc69f1e3cb8f450858eab0e92c3d90ef..14733202d9585c21f050eef5c0aced5c0528dd89 100644
--- a/ExpressAPI/src/config/Config.ts
+++ b/ExpressAPI/src/config/Config.ts
@@ -1,6 +1,3 @@
-import Toolbox from '../shared/helpers/Toolbox';
-
-
 class Config {
     private static _instance: Config;
 
@@ -8,10 +5,6 @@ class Config {
         port: number
     };
 
-    public readonly database: {
-        type: string, host: string, port: number, user: string, password: string, database: string
-    };
-
     public jwtConfig: {
         secret: string; expiresIn: number;
     };
@@ -40,15 +33,6 @@ class Config {
             port: Number(process.env.API_PORT)
         };
 
-        this.database = {
-            type    : process.env.DATABASE_TYPE,
-            host    : process.env.DATABASE_HOST,
-            port    : Number(process.env.DATABASE_PORT),
-            user    : process.env.DATABASE_USER,
-            password: process.env.DATABASE_PASSWORD,
-            database: process.env.DATABASE_NAME
-        };
-
         this.jwtConfig = {
             secret   : process.env.JWT_SECRET_KEY,
             expiresIn: Number(process.env.SESSION_TIMEOUT)
diff --git a/ExpressAPI/src/controllers/Session.ts b/ExpressAPI/src/controllers/Session.ts
index aa6fdd363cf430789fd13985ab2307401db8c816..3abcc186dc9bc024fbebd6ad4f5ddcc3c896a619 100644
--- a/ExpressAPI/src/controllers/Session.ts
+++ b/ExpressAPI/src/controllers/Session.ts
@@ -3,20 +3,21 @@ import * as jwt            from 'jsonwebtoken';
 import { JwtPayload }      from 'jsonwebtoken';
 import Config              from '../config/Config';
 import express             from 'express';
-import ApiRequest          from '../models/ApiRequest';
-import User                from '../models/User';
+import ApiRequest          from '../types/ApiRequest';
 import UserManager         from '../managers/UserManager';
+import DojoResponse        from '../shared/types/DojoResponse';
+import { User }            from '../types/DatabaseTypes';
 
 
 class Session {
-    private _profile: User = new User();
+    private _profile: User;
 
     get profile(): User {
         return this._profile;
     }
 
     set profile(newProfile: User) {
-        newProfile.currentSession = this;
+        delete newProfile.password;
         this._profile = newProfile;
     }
 
@@ -31,9 +32,8 @@ class Session {
                 const jwtData = jwt.verify(jwtToken, Config.jwtConfig.secret) as JwtPayload;
 
                 if ( jwtData.profile ) {
-                    this.profile.importFromJsonObject(jwtData.profile);
-                    this.profile = await UserManager.getById(this.profile.userId);
-                    this.profile.currentSession = this;
+                    this.profile = jwtData.profile;
+                    this.profile = await UserManager.getById(this.profile.id);
                 }
             } catch ( err ) { }
         }
@@ -43,8 +43,8 @@ class Session {
         return profileJson.id === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {});
     }
 
-    private async getResponse(code: number, data: any, descriptionOverride?: string): Promise<any> {
-        const profileJson = await this.profile.toJsonObject();
+    private async getResponse<T>(code: number, data: T, descriptionOverride?: string): Promise<DojoResponse<T>> {
+        const profileJson = this.profile;
 
         let reasonPhrase = '';
 
diff --git a/ExpressAPI/src/helpers/DatabaseHelper.ts b/ExpressAPI/src/helpers/DatabaseHelper.ts
index 97158765ce258ed4fa98c414e9351853df4ac374..89ec9c767cb8f879011a7f5e547eb1942657de7b 100644
--- a/ExpressAPI/src/helpers/DatabaseHelper.ts
+++ b/ExpressAPI/src/helpers/DatabaseHelper.ts
@@ -1,11 +1,35 @@
-import knex   from 'knex';
-import Config from '../config/Config';
+import { PrismaClient }    from '@prisma/client';
+import logger              from '../shared/logging/WinstonLogger';
+import UserQueryExtension  from './Prisma/Extensions/UserQueryExtension';
+import UserResultExtension from './Prisma/Extensions/UserResultExtension';
 
 
-const db = knex({
-                    client    : Config.database.type,
-                    connection: Config.database
-                });
+const prisma = new PrismaClient({
+                                    log: [ {
+                                        emit : 'event',
+                                        level: 'query'
+                                    }, {
+                                        emit : 'event',
+                                        level: 'info'
+                                    }, {
+                                        emit : 'event',
+                                        level: 'warn'
+                                    }, {
+                                        emit : 'event',
+                                        level: 'error'
+                                    } ]
+                                });
 
+prisma.$on('query', e => {
+    logger.debug(`Prisma => Query (${ e.duration }ms): ${ e.query }`);
+    logger.debug(`Prisma => Params: ${ e.params }\n`);
+});
+prisma.$on('info', e => logger.info(`Prisma => ${ e.message }`));
+prisma.$on('warn', e => logger.warn(`Prisma => ${ e.message }`));
+prisma.$on('error', e => logger.error(`Prisma => ${ e.message }`));
 
-export default db;
+
+const db = prisma.$extends(UserQueryExtension).$extends(UserResultExtension);
+
+
+export default db;
\ No newline at end of file
diff --git a/ExpressAPI/src/helpers/Prisma/Extensions/UserQueryExtension.ts b/ExpressAPI/src/helpers/Prisma/Extensions/UserQueryExtension.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0627c773f1f436f8710bf4ee75dd074266f50dc9
--- /dev/null
+++ b/ExpressAPI/src/helpers/Prisma/Extensions/UserQueryExtension.ts
@@ -0,0 +1,31 @@
+import { Prisma } from '@prisma/client';
+
+
+export default Prisma.defineExtension(client => {
+    return client.$extends({
+                               query: {
+                                   user: {
+                                       async delete({
+                                                        args
+                                                    }) {
+
+                                           return client.user.update(Object.assign(args, {
+                                               data: {
+                                                   deleted: true
+                                               }
+                                           }));
+                                       },
+                                       async deleteMany({
+                                                            args
+                                                        }) {
+
+                                           return client.user.updateMany(Object.assign(args, {
+                                               data: {
+                                                   deleted: true
+                                               }
+                                           }));
+                                       }
+                                   }
+                               }
+                           });
+});
\ No newline at end of file
diff --git a/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts b/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts
new file mode 100644
index 0000000000000000000000000000000000000000..604b6de6a9a8dd619928c9fdd6ee5030b2ee574e
--- /dev/null
+++ b/ExpressAPI/src/helpers/Prisma/Extensions/UserResultExtension.ts
@@ -0,0 +1,33 @@
+import { Prisma }    from '@prisma/client';
+import Config        from '../../../config/Config';
+import LazyVal       from '../../../shared/helpers/LazyVal';
+import GitlabUser    from '../../../shared/types/Gitlab/GitlabUser';
+import GitlabManager from '../../../managers/GitlabManager';
+
+
+export default Prisma.defineExtension(client => {
+    return client.$extends({
+                               result: {
+                                   user: {
+                                       isTeachingStaff: {
+                                           needs: {
+                                               role: true
+                                           },
+                                           compute(user) {
+                                               return Config.permissions.teachingStaff.includes(user.role);
+                                           }
+                                       },
+                                       gitlabProfile  : {
+                                           needs: {
+                                               gitlabId: true
+                                           },
+                                           compute(user) {
+                                               return new LazyVal<GitlabUser>(() => {
+                                                   return GitlabManager.getUserById(user.gitlabId);
+                                               });
+                                           }
+                                       }
+                                   }
+                               }
+                           });
+});
\ No newline at end of file
diff --git a/ExpressAPI/src/managers/EnonceManager.ts b/ExpressAPI/src/managers/EnonceManager.ts
index 03022d84827911a5f4e5c44bba8f902698c4fba2..126446442a237230e80da1cdd2915d9178f9ae59 100644
--- a/ExpressAPI/src/managers/EnonceManager.ts
+++ b/ExpressAPI/src/managers/EnonceManager.ts
@@ -1,5 +1,6 @@
-import db     from '../helpers/DatabaseHelper';
-import Enonce from '../models/Enonce';
+import { Prisma } from '@prisma/client';
+import { Enonce } from '../types/DatabaseTypes';
+import db         from '../helpers/DatabaseHelper';
 
 
 class EnonceManager {
@@ -15,30 +16,24 @@ class EnonceManager {
         return EnonceManager._instance;
     }
 
-    createObjectFromRawSql(raw: any): Enonce {
-        const enonce = Enonce.createFromSql(raw);
-
-        enonce.enonceGitlabCreationInfo = raw.enonceGitlabCreationInfo;
-        enonce.enonceGitlabLastInfo = raw.enonceGitlabLastInfo;
-
-        return enonce;
-    }
-
-    async getByName(name: string): Promise<Enonce | undefined> {
-        const raw = await db<Enonce>(Enonce.tableName).where('enonceName', name).first();
-
-        return raw ? this.createObjectFromRawSql(raw) : undefined;
+    async getByName(name: string, include: Prisma.EnonceInclude | undefined = undefined): Promise<Enonce | undefined> {
+        return db.enonce.findUnique({
+                                        where  : {
+                                            name: name
+                                        },
+                                        include: include
+                                    });
     }
 
-    getByGitlabLink(gitlabLink: string): Promise<Enonce | undefined> {
+    getByGitlabLink(gitlabLink: string, include: Prisma.EnonceInclude | undefined = undefined): Promise<Enonce | undefined> {
         const name = gitlabLink.replace('.git', '').split('/').pop();
 
-        return this.getByName(name);
+        return this.getByName(name, include);
     }
 
-    get(nameOrUrl: string): Promise<Enonce | undefined> {
+    get(nameOrUrl: string, include: Prisma.EnonceInclude | undefined = undefined): Promise<Enonce | undefined> {
         // We can use the same function for both name and url because the name is the last part of the url and the name extraction from the url doesn't corrupt the name
-        return this.getByGitlabLink(nameOrUrl);
+        return this.getByGitlabLink(nameOrUrl, include);
     }
 }
 
diff --git a/ExpressAPI/src/managers/GitlabManager.ts b/ExpressAPI/src/managers/GitlabManager.ts
index d1a6d5d9c29b2ab2055e57efa161935127b44b83..8474c7db75277b916546c49ff7378dc303a67a71 100644
--- a/ExpressAPI/src/managers/GitlabManager.ts
+++ b/ExpressAPI/src/managers/GitlabManager.ts
@@ -113,7 +113,7 @@ class GitlabManager {
         };
         members.forEach(member => {
             if ( member.access_level >= GitlabAccessLevel.REPORTER ) {
-                if ( member.id === req.session.profile.userGitlabId ) {
+                if ( member.id === req.session.profile.gitlabId ) {
                     isUsersAtLeastReporter.user = true;
                 } else if ( member.id === Config.gitlab.account.id ) {
                     isUsersAtLeastReporter.dojo = true;
diff --git a/ExpressAPI/src/managers/UserManager.ts b/ExpressAPI/src/managers/UserManager.ts
index 748ca4c6248f2cd871d33cc1acd2065278801162..545683878358a0970adca8d37835c6a50d2e1498 100644
--- a/ExpressAPI/src/managers/UserManager.ts
+++ b/ExpressAPI/src/managers/UserManager.ts
@@ -1,7 +1,7 @@
-import User        from '../models/User';
-import db          from '../helpers/DatabaseHelper';
-import GitlabUser  from '../shared/types/Gitlab/GitlabUser';
-import EnonceStaff from '../models/EnonceStaff';
+import GitlabUser from '../shared/types/Gitlab/GitlabUser';
+import { Prisma } from '@prisma/client';
+import db         from '../helpers/DatabaseHelper';
+import { User }   from '../types/DatabaseTypes';
 
 
 class UserManager {
@@ -17,59 +17,50 @@ class UserManager {
         return UserManager._instance;
     }
 
-    createObjectFromRawSql(raw: any): User {
-        return User.createFromSql(raw);
+    async getByMail(mail: string, include: Prisma.UserInclude | undefined = undefined): Promise<User | undefined> {
+        return db.user.findUnique({
+                                      where  : {
+                                          mail: mail
+                                      },
+                                      include: include
+                                  });
     }
 
-    async getByMail(mail: string): Promise<User | undefined> {
-        const raw = await db<User>(User.tableName).where('userMail', mail).first();
-
-        return raw ? this.createObjectFromRawSql(raw) : undefined;
-    }
-
-    async getById(id: number): Promise<User | undefined> {
-        const raw = await db<User>(User.tableName).where('userId', id).first();
-
-        return raw ? this.createObjectFromRawSql(raw) : undefined;
-    }
-
-    async getByIds(ids: Array<number>): Promise<Array<User>> {
-        return Promise.all(ids.map(userId => this.getById(userId)));
+    async getById(id: number, include: Prisma.UserInclude | undefined = undefined): Promise<User | undefined> {
+        return await db.user.findUnique({
+                                            where  : {
+                                                id: id
+                                            },
+                                            include: include
+                                        });
     }
 
-    async getByGitlabId(gitlabId: number): Promise<User | number> {
-        const raw = await db<User>(User.tableName).where('userGitlabId', gitlabId).first();
-
-        return raw ? this.createObjectFromRawSql(raw) : gitlabId;
-    }
-
-    async getByGitlabIds(gitlabIds: Array<number>): Promise<Array<User | number>> {
-        return Promise.all(gitlabIds.map(gitlabId => this.getByGitlabId(gitlabId)));
+    async getByGitlabId(gitlabId: number, returnIdIfUndefined: boolean = true, include: Prisma.UserInclude | undefined = undefined): Promise<User | number | undefined> {
+        return (await db.user.findUnique({
+                                             where  : {
+                                                 gitlabId: gitlabId
+                                             },
+                                             include: include
+                                         })) ?? (returnIdIfUndefined ? gitlabId : undefined);
     }
 
-    async getFromGitlabUser(gitlabUser: GitlabUser, createIfNotExist: boolean = false): Promise<User | number> {
-        let user = await this.getByGitlabId(gitlabUser.id);
+    async getFromGitlabUser(gitlabUser: GitlabUser, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<User | number> {
+        let user = await this.getByGitlabId(gitlabUser.id, true, include);
 
         if ( typeof user === 'number' && createIfNotExist ) {
-            user = await User.createFromSql({
-                                                userFirstName: gitlabUser.name,
-                                                userGitlabId : gitlabUser.id
-                                            }).create();
+            user = (await db.user.create({
+                                             data: {
+                                                 firstname: gitlabUser.name,
+                                                 gitlabId : gitlabUser.id
+                                             }
+                                         })).id;
         }
 
         return user;
     }
 
-    async getFromGitlabUsers(gitlabUsers: Array<GitlabUser>, createIfNotExist: boolean = false): Promise<Array<User | number>> {
-        return Promise.all(gitlabUsers.map(gitlabUser => this.getFromGitlabUser(gitlabUser, createIfNotExist)));
-    }
-
-    async getStaffOfEnonce(enonceName: string): Promise<Array<User>> {
-        const raw = await db<User>(User.tableName)
-        .innerJoin(EnonceStaff.tableName, `${ EnonceStaff.tableName }.userId`, `${ User.tableName }.userId`)
-        .where('enonceName', enonceName);
-
-        return raw ? raw.map(user => this.createObjectFromRawSql(user)) : [];
+    async getFromGitlabUsers(gitlabUsers: Array<GitlabUser>, createIfNotExist: boolean = false, include: Prisma.UserInclude | undefined = undefined): Promise<Array<User | number>> {
+        return Promise.all(gitlabUsers.map(gitlabUser => this.getFromGitlabUser(gitlabUser, createIfNotExist, include)));
     }
 }
 
diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
index 7626cde6992de4b765145a57eb3069cf93b3c249..4c09baa0c2f7bae21dcd62e9caaa0891a09231e2 100644
--- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -1,5 +1,5 @@
 import { Express }     from 'express-serve-static-core';
-import ApiRequest      from '../models/ApiRequest';
+import ApiRequest      from '../types/ApiRequest';
 import express         from 'express';
 import { StatusCodes } from 'http-status-codes';
 import EnonceManager   from '../managers/EnonceManager';
@@ -18,9 +18,9 @@ class ParamsCallbackManager {
         return ParamsCallbackManager._instance;
     }
 
-    protected listenParam(paramName: string, backend: Express, context: any, functionName: string, indexName: string) {
+    protected listenParam(paramName: string, backend: Express, getFunction: (id: string | number, ...args: Array<any>) => Promise<any>, args: Array<any>, indexName: string) {
         backend.param(paramName, (req: ApiRequest, res: express.Response, next: express.NextFunction, id: string | number) => {
-            (context[functionName] as (id: string | number) => Promise<any>)(id).then(result => {
+            getFunction(id, ...args).then(result => {
                 if ( result ) {
                     this.initBoundParams(req);
                     (req.boundParams as any)[indexName] = result;
@@ -42,7 +42,15 @@ class ParamsCallbackManager {
     }
 
     register(backend: Express) {
-        this.listenParam('enonceNameOrUrl', backend, EnonceManager, 'get', 'enonce');
+        this.listenParam('enonceNameOrUrl',
+                         backend,
+                         EnonceManager.get.bind(EnonceManager),
+                         [ {
+                             exercices: true,
+                             staff: true
+                         } ],
+                         'enonce'
+        );
     }
 }
 
diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
index cce4344c0d606560e1166d853074e965760c03f3..a48803754c61d05df9dee9e2111864439ada4026 100644
--- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts
+++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
@@ -2,7 +2,7 @@ import express           from 'express';
 import { StatusCodes }   from 'http-status-codes';
 import SecurityCheckType from '../types/SecurityCheckType';
 import logger            from '../shared/logging/WinstonLogger';
-import ApiRequest        from '../models/ApiRequest';
+import ApiRequest        from '../types/ApiRequest';
 
 
 class SecurityMiddleware {
@@ -22,7 +22,7 @@ class SecurityMiddleware {
     check(checkIfConnected: boolean, ...checkTypes: Array<SecurityCheckType>): (req: ApiRequest, res: express.Response, next: express.NextFunction) => void {
         return async (req: ApiRequest, res: express.Response, next: express.NextFunction) => {
             if ( checkIfConnected ) {
-                if ( req.session.profile.userId === null ) {
+                if ( req.session.profile.id === null ) {
                     return req.session.sendResponse(res, StatusCodes.UNAUTHORIZED);
                 }
             }
diff --git a/ExpressAPI/src/routes/EnonceRoutes.ts b/ExpressAPI/src/routes/EnonceRoutes.ts
index bd4e1dbc422c3d079f49db5d661101aa69833dc6..1a5843759c88553a48f32e7895243c1b2c71eab2 100644
--- a/ExpressAPI/src/routes/EnonceRoutes.ts
+++ b/ExpressAPI/src/routes/EnonceRoutes.ts
@@ -13,14 +13,12 @@ import Config                    from '../config/Config';
 import GitlabMember              from '../shared/types/Gitlab/GitlabMember';
 import GitlabAccessLevel         from '../shared/types/Gitlab/GitlabAccessLevel';
 import GitlabRepository          from '../shared/types/Gitlab/GitlabRepository';
-import UserManager               from '../managers/UserManager';
-import User                      from '../models/User';
-import Enonce                    from '../models/Enonce';
-import EnonceStaff               from '../models/EnonceStaff';
 import { AxiosError }            from 'axios';
 import logger                    from '../shared/logging/WinstonLogger';
 import DojoValidators            from '../helpers/DojoValidators';
-import EnonceManager             from '../managers/EnonceManager';
+import { Prisma }                from '@prisma/client';
+import db                        from '../helpers/DatabaseHelper';
+import { Enonce }                from '../types/DatabaseTypes';
 
 
 class EnonceRoutes implements RoutesManager {
@@ -60,11 +58,14 @@ class EnonceRoutes implements RoutesManager {
 
     // Get an enonce by its name or gitlab url
     private async getEnonce(req: ApiRequest, res: express.Response) {
-        return req.boundParams.enonce ? req.session.sendResponse(res, StatusCodes.OK, req.boundParams.enonce.toJsonObject()) : res.status(StatusCodes.NOT_FOUND).send();
+        return req.boundParams.enonce ? req.session.sendResponse(res, StatusCodes.OK, req.boundParams.enonce) : res.status(StatusCodes.NOT_FOUND).send();
     }
 
     private async createEnonce(req: ApiRequest, res: express.Response) {
         const params: { name: string, members: Array<GitlabUser>, template: string } = req.body;
+        params.members = [ await req.session.profile.gitlabProfile.value, ...params.members ];
+        params.members = params.members.removeObjectDuplicates(gitlabUser => gitlabUser.id);
+
 
         let repository: GitlabRepository;
         try {
@@ -83,31 +84,39 @@ class EnonceRoutes implements RoutesManager {
         }
 
         try {
-            const members: Array<GitlabMember | false> = await Promise.all([ req.session.profile.userGitlabId, ...params.members.map(member => member.id) ].map(async (memberId: number): Promise<GitlabMember | false> => {
+            await Promise.all(params.members.map(member => member.id).map(async (memberId: number): Promise<GitlabMember | false> => {
                 try {
-                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.Maintainer);
+                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.DEVELOPER);
                 } catch ( e ) {
                     return false;
                 }
             }));
 
-            const enonce: Enonce = await EnonceManager.createObjectFromRawSql({
-                                                                                  enonceName              : repository.name,
-                                                                                  enonceGitlabId          : repository.id,
-                                                                                  enonceGitlabLink        : repository.web_url,
-                                                                                  enonceGitlabCreationInfo: JSON.stringify(repository),
-                                                                                  enonceGitlabLastInfo    : JSON.stringify(repository),
-                                                                                  enonceGitlabLastInfoTs  : new Date().getTime()
-                                                                              }).create();
-
-            let dojoUsers: Array<User> = [ req.session.profile, ...(await UserManager.getFromGitlabUsers(params.members, true) as Array<User>) ];
-            dojoUsers = dojoUsers.reduce((unique, user) => (unique.findIndex(uniqueUser => uniqueUser.userId === user.userId) !== -1 ? unique : [ ...unique, user ]), Array<User>());
-            await Promise.all(dojoUsers.map(dojoUser => EnonceStaff.createFromSql({
-                                                                                      enonceName: enonce.enonceName,
-                                                                                      userId    : dojoUser.userId
-                                                                                  }).create()));
-
-            return req.session.sendResponse(res, StatusCodes.OK, enonce.toJsonObject());
+            const enonce: Enonce = await db.enonce.create({
+                                                              data: {
+                                                                  name              : repository.name,
+                                                                  gitlabId          : repository.id,
+                                                                  gitlabLink        : repository.web_url,
+                                                                  gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
+                                                                  gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
+                                                                  gitlabLastInfoDate: new Date(),
+                                                                  staff             : {
+                                                                      connectOrCreate: [ ...params.members.map(gitlabUser => {
+                                                                          return {
+                                                                              create: {
+                                                                                  gitlabId : gitlabUser.id,
+                                                                                  firstname: gitlabUser.name
+                                                                              },
+                                                                              where : {
+                                                                                  gitlabId: gitlabUser.id
+                                                                              }
+                                                                          };
+                                                                      }) ]
+                                                                  }
+                                                              }
+                                                          });
+
+            return req.session.sendResponse(res, StatusCodes.OK, enonce);
         } catch ( error ) {
             if ( error instanceof AxiosError ) {
                 return res.status(error.response.status).send();
diff --git a/ExpressAPI/src/routes/ExerciceRoutes.ts b/ExpressAPI/src/routes/ExerciceRoutes.ts
index 3f7832004cf56d8333b5eba83dd4665980ee3b74..840f4ed221381dc3753dc4ecf69b4be4eca7193b 100644
--- a/ExpressAPI/src/routes/ExerciceRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciceRoutes.ts
@@ -10,18 +10,15 @@ import GitlabUser                from '../shared/types/Gitlab/GitlabUser';
 import GitlabManager             from '../managers/GitlabManager';
 import Config                    from '../config/Config';
 import GitlabRepository          from '../shared/types/Gitlab/GitlabRepository';
-import Enonce                    from '../models/Enonce';
 import { AxiosError }            from 'axios';
 import logger                    from '../shared/logging/WinstonLogger';
 import DojoValidators            from '../helpers/DojoValidators';
 import { v4 as uuidv4 }          from 'uuid';
 import GitlabMember              from '../shared/types/Gitlab/GitlabMember';
 import GitlabAccessLevel         from '../shared/types/Gitlab/GitlabAccessLevel';
-import User                      from '../models/User';
-import UserManager               from '../managers/UserManager';
-import Exercice                  from '../models/Exercice';
-import ExerciceMember            from '../models/ExerciceMember';
-import ExerciceManager           from '../managers/ExerciceManager';
+import { Prisma }                from '@prisma/client';
+import { Enonce, Exercice }      from '../types/DatabaseTypes';
+import db                        from '../helpers/DatabaseHelper';
 
 
 class ExerciceRoutes implements RoutesManager {
@@ -50,24 +47,26 @@ class ExerciceRoutes implements RoutesManager {
     }
 
     private getExerciceName(enonce: Enonce, members: Array<GitlabUser>, suffix: number): string {
-        return `DojoEx - ${ enonce.enonceName } - ${ members.map(member => member.username).join(' + ') }${ suffix > 0 ? ` - ${ suffix }` : '' }`;
+        return `DojoEx - ${ enonce.name } - ${ members.map(member => member.username).join(' + ') }${ suffix > 0 ? ` - ${ suffix }` : '' }`;
     }
 
     private getExercicePath(enonce: Enonce, exerciceId: string): string {
-        return `dojo-ex_${ enonce.enonceGitlabLastInfo.path }_${ exerciceId }`;
+        return `dojo-ex_${ (enonce.gitlabLastInfo as unknown as GitlabRepository).path }_${ exerciceId }`;
     }
 
     private async createExercice(req: ApiRequest, res: express.Response) {
         const params: { members: Array<GitlabUser> } = req.body;
-        params.members = [ await req.session.profile.gitlabProfile.value, ...params.members ];
+        params.members = [ await req.session.profile.gitlabProfile.value, ...params.members ].removeObjectDuplicates(gitlabUser => gitlabUser.id);
+        const enonce: Enonce = req.boundParams.enonce;
 
-        const exerciceId: string = uuidv4();
 
+        const exerciceId: string = uuidv4();
         let repository: GitlabRepository;
+
         let suffix: number = 0;
         do {
             try {
-                repository = await GitlabManager.forkRepository(req.boundParams.enonce.enonceGitlabCreationInfo.id, this.getExerciceName(req.boundParams.enonce, params.members, suffix), this.getExercicePath(req.boundParams.enonce, exerciceId), Config.exercice.default.description.replace('{{ENONCE_NAME}}', req.boundParams.enonce.enonceName), Config.exercice.default.visibility, Config.gitlab.group.exercices);
+                repository = await GitlabManager.forkRepository((enonce.gitlabCreationInfo as unknown as GitlabRepository).id, this.getExerciceName(enonce, params.members, suffix), this.getExercicePath(req.boundParams.enonce, exerciceId), Config.exercice.default.description.replace('{{ENONCE_NAME}}', enonce.name), Config.exercice.default.visibility, Config.gitlab.group.exercices);
                 break;
             } catch ( error ) {
                 if ( error instanceof AxiosError ) {
@@ -87,33 +86,41 @@ class ExerciceRoutes implements RoutesManager {
         }
 
         try {
-            const members: Array<GitlabMember | false> = await Promise.all([ ...new Set([ ...(await req.boundParams.enonce.staff.value).map(member => member.userGitlabId), ...params.members.map(member => member.id) ]) ].map(async (memberId: number): Promise<GitlabMember | false> => {
+            await Promise.all([ ...new Set([ ...enonce.staff.map(user => user.gitlabId), ...params.members.map(member => member.id) ]) ].map(async (memberId: number): Promise<GitlabMember | false> => {
                 try {
-                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.Maintainer);
+                    return await GitlabManager.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.DEVELOPER);
                 } catch ( e ) {
                     return false;
                 }
             }));
 
-            const exercice: Exercice = await ExerciceManager.createObjectFromRawSql({
-                                                                                        exerciceId                : exerciceId,
-                                                                                        exerciceEnonceName        : req.boundParams.enonce.enonceName,
-                                                                                        exerciceName              : repository.name,
-                                                                                        exerciceGitlabId          : repository.id,
-                                                                                        exerciceGitlabLink        : repository.web_url,
-                                                                                        exerciceGitlabCreationInfo: JSON.stringify(repository),
-                                                                                        exerciceGitlabLastInfo    : JSON.stringify(repository),
-                                                                                        exerciceGitlabLastInfoTs  : new Date().getTime()
-                                                                                    }).create();
-
-            let dojoUsers: Array<User> = await UserManager.getFromGitlabUsers(params.members, true) as Array<User>;
-            dojoUsers = dojoUsers.reduce((unique, user) => (unique.findIndex(uniqueUser => uniqueUser.userId === user.userId) !== -1 ? unique : [ ...unique, user ]), Array<User>());
-            await Promise.all(dojoUsers.map(dojoUser => ExerciceMember.createFromSql({
-                                                                                         exerciceId: exercice.exerciceId,
-                                                                                         userId    : dojoUser.userId
-                                                                                     }).create()));
-
-            return req.session.sendResponse(res, StatusCodes.OK, exercice.toJsonObject());
+            const exercice: Exercice = await db.exercice.create({
+                                                                    data: {
+                                                                        id                : exerciceId,
+                                                                        enonceName        : enonce.name,
+                                                                        name              : repository.name,
+                                                                        gitlabId          : repository.id,
+                                                                        gitlabLink        : repository.web_url,
+                                                                        gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
+                                                                        gitlabLastInfo    : repository as unknown as Prisma.JsonObject,
+                                                                        gitlabLastInfoDate: new Date(),
+                                                                        members           : {
+                                                                            connectOrCreate: [ ...params.members.map(gitlabUser => {
+                                                                                return {
+                                                                                    create: {
+                                                                                        gitlabId : gitlabUser.id,
+                                                                                        firstname: gitlabUser.name
+                                                                                    },
+                                                                                    where : {
+                                                                                        gitlabId: gitlabUser.id
+                                                                                    }
+                                                                                };
+                                                                            }) ]
+                                                                        }
+                                                                    }
+                                                                });
+
+            return req.session.sendResponse(res, StatusCodes.OK, exercice);
         } catch ( error ) {
             if ( error instanceof AxiosError ) {
                 return res.status(error.response.status).send();
diff --git a/ExpressAPI/src/routes/SessionRoutes.ts b/ExpressAPI/src/routes/SessionRoutes.ts
index b74019b093071abbc777723b6fb6b519d248e24b..08c3f35b098fd96042016016bb25aff5fe5a6d81 100644
--- a/ExpressAPI/src/routes/SessionRoutes.ts
+++ b/ExpressAPI/src/routes/SessionRoutes.ts
@@ -7,8 +7,8 @@ import RoutesManager             from '../express/RoutesManager';
 import ParamsValidatorMiddleware from '../middlewares/ParamsValidatorMiddleware';
 import ApiRequest                from '../types/ApiRequest';
 import UserManager               from '../managers/UserManager';
-import User                      from '../models/User';
 import SecurityMiddleware        from '../middlewares/SecurityMiddleware';
+import { User }                  from '../types/DatabaseTypes';
 
 
 class SessionRoutes implements RoutesManager {
@@ -46,7 +46,7 @@ class SessionRoutes implements RoutesManager {
         const user: User | undefined = await UserManager.getByMail(params.user);
 
         if ( user ) {
-            if ( bcrypt.compareSync(params.password, user.userPassword) ) {
+            if ( bcrypt.compareSync(params.password, user.password) ) {
                 req.session.profile = user;
 
                 req.session.sendResponse(res, StatusCodes.OK);
diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a782d9a66d98cf9ecb7043c7a057dca23a92e700
--- /dev/null
+++ b/ExpressAPI/src/types/DatabaseTypes.ts
@@ -0,0 +1,34 @@
+import { Prisma } from '@prisma/client';
+import LazyVal    from '../shared/helpers/LazyVal';
+import GitlabUser from '../shared/types/Gitlab/GitlabUser';
+
+
+const userBase = Prisma.validator<Prisma.UserArgs>()({
+                                                         include: { exercices: true }
+                                                     });
+const enonceBase = Prisma.validator<Prisma.EnonceArgs>()({
+                                                             include: {
+                                                                 exercices: true,
+                                                                 staff    : true
+                                                             }
+                                                         });
+const exerciceBase = Prisma.validator<Prisma.ExerciceArgs>()({
+                                                                 include: {
+                                                                     members: true,
+                                                                     results: true
+                                                                 }
+                                                             });
+const resultBase = Prisma.validator<Prisma.ResultArgs>()({
+                                                             include: {
+                                                                 exercice: true
+                                                             }
+                                                         });
+
+
+export type User = Partial<Prisma.UserGetPayload<typeof userBase> & {
+    isTeachingStaff: boolean
+    gitlabProfile: LazyVal<GitlabUser>
+}>
+export type Enonce = Partial<Prisma.EnonceGetPayload<typeof enonceBase>>
+export type Exercice = Partial<Prisma.ExerciceGetPayload<typeof exerciceBase>>
+export type Result = Partial<Prisma.ResultGetPayload<typeof resultBase>>
\ No newline at end of file